#pragma once
#include <iostream>
#include <cassert>
#include "Reverse_iterator.hpp"
namespace aoqiang
{
    // 节点类型
    template <class T>
    struct ListNode
    {
        ListNode<T> *next_;
        ListNode<T> *prev_;
        T val_;
        ListNode(const T &val = T())
            : next_(nullptr), prev_(nullptr), val_(val)
        {
        }
    };

    // 普通迭代器类型
    // template <class T>
    // struct _list_iterator
    // {
    //     typedef ListNode<T> Node;
    //     Node *node_;
    //     _list_iterator(Node *node) : node_(node)
    //     {
    //     }
    //     T &operator*()
    //     {
    //         return node_->val_;
    //     }
    //     _list_iterator operator++()
    //     {
    //         node_ = node_->next_;
    //         return *this;
    //     }
    //     _list_iterator operator++(int)
    //     {
    //         _list_iterator<T> tmp(*this);
    //         node_ = node_->next_;
    //         return tmp;
    //     }
    //     bool operator!=(const _list_iterator<T> &it)
    //     {
    //         return node_ != it.node_;
    //     }
    //     bool operator==(const _list_iterator<T> &it)
    //     {
    //         return node_ == it.node_;
    //     }
    // }
    // const 迭代器类型
    //! 这样设计的话，其实只有解引用的返回值类型不一样，其余都是相同的，可以实现，但是好像有点冗余
    // template <class T>
    // struct _list_const_iterator
    // {
    //     typedef ListNode<T> Node;
    //     Node *node_;
    //     _list_const_iterator(Node *node) : node_(node)
    //     {
    //     }
    //     const T &operator*()
    //     {
    //         return node_->val_;
    //     }
    //     _list_const_iterator operator++()
    //     {
    //         node_ = node_->next_;
    //         return *this;
    //     }
    //     _list_const_iterator operator++(int)
    //     {
    //         _list_iterator<T> tmp(*this);
    //         node_ = node_->next_;
    //         return tmp;
    //     }
    //     bool operator!=(const _list_iterator<T> &it)
    //     {
    //         return node_ != it.node_;
    //     }
    //     bool operator==(const _list_iterator<T> &it)
    //     {
    //         return node_ == it.node_;
    //     }
    // }

    template <class T, class Ref, class Ptr>
    struct _list_iterator
    {
        typedef ListNode<T> Node;
        typedef _list_iterator<T, Ref, Ptr> self;
        Node *node_;
        _list_iterator(Node *node) : node_(node)
        {
        }
        Ref operator*()
        {
            return node_->val_;
        }
        self &operator++()
        {
            node_ = node_->next_;
            return *this;
        }
        self operator++(int)
        {
            self tmp(*this);
            node_ = node_->next_;
            return tmp;
        }
        self &operator--()
        {
            node_ = node_->prev_;
            return *this;
        }
        self operator--(int)
        {
            self tmp(*this);
            node_ = node_->prev_;
            return tmp;
        }
        Ptr operator->()
        {
            return &node_->val_;
        }
        bool operator!=(const self &it)const
        {
            return node_ != it.node_;
        }
        bool operator==(const self &it)const
        {
            return node_ == it.node_;
        }
    };

    template <class T>
    class list
    {
        typedef ListNode<T> Node;

    public:
        typedef _list_iterator<T, T &, T *> iterator;
        typedef _list_iterator<T, const T &, const T *> const_iterator;

        typedef ReverseIterator<iterator, T &, T *> reverse_iterator;
        typedef ReverseIterator<const_iterator, const T &, const T *> const_reverse_iterator;

    public:
        list()
        {
            head_ = new Node();
            head_->next_ = nullptr;
            head_->prev_ = nullptr;
        }
        iterator begin()
        {
            return iterator(head_->next_);
        }
        iterator end()
        {
            return iterator(head_);
        }
        const_iterator begin() const
        {
            return const_iterator(head_->next_);
        }
        const_iterator end() const
        {
            return const_iterator(head_);
        }
        reverse_iterator rbegin()
        {
            return reverse_iterator(end());
        }
        reverse_iterator rend()
        {
            return reverse_iterator(begin());
        }

        ~list() {}
        void push_back(const T &t)
        {
            Node *tail = head_->prev_;
            Node *newnode = new Node(t);
            if (tail == nullptr)
            {
                head_->next_ = newnode;
                newnode->prev_ = head_;

                head_->prev_ = newnode;
            }
            else
            {
                tail->next_ = newnode;
                newnode->prev_ = tail;

                newnode->next_ = head_;
                head_->prev_ = newnode;
            }
        }
        void pop_back()
        {
            assert(head_->next_ != nullptr);
            Node *tail = head_->prev_;
            Node *prev = tail->prev_;

            prev->next_ = head_;
            head_->prev_ = prev;

            delete tail;
        }
        void push_front(const T &t)
        {
            Node *first = head_->next_;
            Node *newnode = new Node(t);

            head_->next_ = newnode;
            newnode->prev_ = head_;

            newnode->next_ = first;
            first->prev_ = newnode;
        }
        void pop_front()
        {
            assert(head_->next_ != nullptr);

            Node *first = head_->next_;
            Node *second = first->next_;
            if (second == nullptr)
            {
                head_->next_ = head_->prev_ = nullptr;
            }
            else
            {
                head_->next_ = second;
                second->prev_ = head_;
            }
            delete first;
        }

    private:
        Node *head_;
    };

    void Print(aoqiang::list<int> &lt)
    {
        auto it = lt.begin();
        while (it != lt.end())
        {
            // (*it) += 1;
            std::cout << *it << " ";
            ++it;
        }
        std::cout << std::endl;

        list<int>::reverse_iterator rit = lt.rbegin();
            // std::cout << *rit << " ";

        //为什么会调用到正向迭代器的 const类型函数
            //反向迭代器使用的是 正向迭代器的封装，调用的是正向迭代器的 == 和 != ,需要是const
        while (rit != lt.rend())
        {
            std::cout << *rit << " ";
            ++rit;
        }
        std::cout << std::endl;
    }

}